/* eslint-disable object-curly-newline */
const { constantsMap, templateAlias } = require('./constants/mockData');
const objectToString = require('./utils/objectToString');

const ComponentsKeys = Object.keys(constantsMap);
const isWord = (s) => (s >= 'A' && s <= 'Z') || (s >= 'a' && s <= 'z');

// 对组件的别名进行替换
const aliasReplace = (something) => {
  let ret = something;
  const keys = Object.keys(templateAlias);
  if (typeof something === 'string') {
    keys.forEach((k) => {
      ret = something.replace(`<${k}`, `<${templateAlias[k]}`);
    });
  } else if (something instanceof Array) {
    ret = something.map((sth) => {
      if (keys.includes(sth)) {
        return templateAlias[sth];
      }
      return sth;
    });
  }
  return ret;
};

// 根据匹配到的组件名返回声明常量的语句，插入到组件中的语句，声明的types数组
const propsString = (key) => {
  const arr = constantsMap[key];
  let declaration = '';
  let insert = ' ';
  const types = [];
  arr.forEach((a) => {
    const { name, type, value, _init } = a;
    if (type) {
      types.push(type.includes('[]') ? type.slice(0, -2) : type);
    }
    const variable = `${key}_${name}`;
    insert += `${name}={${variable}} `;
    declaration += `const ${variable}${type ? `:${type}` : ''}=${objectToString(
      value
    )};`;
    if (_init) {
      const { insertString } = _init();
      declaration = insertString + declaration;
    }
  });
  return { declaration, insert, types };
};

// 生成引入语句
const generateImports = (yhComponentsAndTypes) => {
  // 别名替换,去重
  const els = [...new Set(aliasReplace(yhComponentsAndTypes))];
  return `import {${els.join(',')}} from '@yh/yh-design';`;
};

// 把模板中的固有常量注入jsx中
const patchConstants = (jsx) => {
  let declarations = '';
  const yhComponentsAndTypes = [];
  if (jsx[0] !== '<' && jsx[jsx.length] !== '>') {
    console.error('FORMAT_ERROR');
    return;
  }
  let newString = '';
  newString = `${jsx}`;
  let i = 0;
  let j = 0;
  let k = 0;
  while (i < newString.length) {
    k = 1;
    if (newString[i] === '<') {
      j = i + 1;
      while (isWord(newString[j])) {
        j += 1;
      }
      // 匹配到单词
      if (j > i + 1) {
        const matchWord = newString.slice(i + 1, j);
        // console.log('matchWord', matchWord);
        if (ComponentsKeys.includes(matchWord)) {
          const { insert, declaration, types } = propsString(matchWord);
          yhComponentsAndTypes.push(matchWord);
          yhComponentsAndTypes.push(...types);
          declarations += declaration;
          const a = newString.slice(0, j);
          const b = newString.slice(j, newString.length);
          newString = a + insert + b;
          k = insert.length;
        } else {
          if (matchWord.includes('YH')) {
            yhComponentsAndTypes.push(matchWord);
          }
          k = 1;
        }
      } else {
        j = 0;
        k = 1;
      }
    }
    i += k;
    // console.log('end-', i, newString[i]);
  }

  // 生成引入语句
  // 去重
  const importStatement = generateImports(yhComponentsAndTypes);
  return {
    insertString: aliasReplace(newString),
    declarations,
    importStatement,
  };
};
// const test = '<div><YHSearch/><YHTable/></div>';
// console.log(patchConstants(test));
module.exports = patchConstants;
